package com.sojson.util.encrypt;

import com.sojson.constant.ConstantByMap;
import com.sojson.util.encrypt.bothway.alike.base64.Base64Util;
import com.sojson.util.encrypt.oneway.alike.md5.Md5Util;

/**
 * 加密工具类
 * 
 * @author liu
 * @date 2020-11-02
 */
public class EncryptUtil {

    /** 要拼接的密钥的长度 */
    public static final int SUFFIX_KEY_LENTH = ConstantByMap.DEFAULT_KEY.length();

    /**
     * 不可逆的加密方法
     * 
     * @param data
     * @return
     * @throws Exception
     */
    public static String encrypt(String data) throws Exception {
        return Md5Util.encryptToUpperCase(data);
    }

    /**
     * 不可逆的加密方法
     * 
     * @param data
     * @param key   加密密钥
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        return Md5Util.encryptToUpperCase(data, key);
    }

    /**
     * 可逆的加密方法
     * 
     * @param data
     * @return
     */
    public static String encryptReverse(String data) {
        return Base64Util.encrypt(data);
    }

    /**
     * 可逆的加密方法
     * 
     * @param data
     * @param key   加密密钥
     * @return
     */
    public static String encryptReverse(String data, String key) {
        return Base64Util.encrypt(data, key);
    }

    /**
     * 解密方法
     * 
     * @param data
     * @return
     */
    public static String decrypt(String data) {
        return Base64Util.decrypt(data);
    }

    /**
     * 解密方法
     * 
     * @param data
     * @param key   解密密钥
     * @return
     */
    public static String decrypt(String data, String key) {
        return Base64Util.decrypt(data, key);
    }

    /**
     * 解密方法
     * 
     * @param data
     * @return
     */
    public static byte[] decrypt(byte[] data) {
        return Base64Util.decrypt(data);
    }

    /**
     * 解密方法
     * 
     * @param data
     * @param key   解密密钥
     * @return
     */
    public static byte[] decrypt(byte[] data, String key) {
        return Base64Util.decrypt(data, key);
    }

    /**
     * 用key对字符串加密,原理: 字符串每个字符对key每个字符进行计算
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static byte[] keyEncrypt(byte[] data, String key) {
        int keyLength = key.length();
        byte[] b = null;
        int charLength = data.length;

        // 字符长度小于key长度
        if (charLength < keyLength) {
            key = key.substring(0, charLength);
        } else if (charLength > keyLength) {
            // 字符长度大于key长度

            StringBuilder stringBuilder = new StringBuilder(key);
            // 字符长度减去key长度后剩余的长度
            int minusLenth = charLength - keyLength;
            // 剩余长度除以要拼接的密钥的长度,得出要拼接几次密钥
            int divide = minusLenth / EncryptUtil.SUFFIX_KEY_LENTH;
            // 拼接密钥
            for (int j = 0; j < divide; j++) {
                stringBuilder.append(ConstantByMap.DEFAULT_KEY);
            }
            // 剩余长度余要拼接的密钥长度,得出拼完后还差几个字符
            int remainder = minusLenth % EncryptUtil.SUFFIX_KEY_LENTH;
            // 拼接剩余字符
            if (remainder != 0) {
                stringBuilder.append(ConstantByMap.DEFAULT_KEY.substring(0, remainder));
            }
            key = stringBuilder.toString();
        }
        b = key.getBytes();
        // 字符串每个字符加上key对应的字符
        for (int i = 0; i < charLength; i++) {
            data[i] += b[i];
        }

        return data;
    }

    /**
     * 用key对字符串解密,原理: 字符串每个字符对key每个字符进行计算
     * 
     * @param data  内容
     * @param key   密钥
     * @return
     */
    public static byte[] keyDecrypt(byte[] data, String key) {
        int keyLength = key.length();
        byte[] b = null;
        int charLength = data.length;

        // 字符长度小于key长度
        if (charLength < keyLength) {
            key = key.substring(0, charLength);
        } else if (charLength > keyLength) {
            // 字符长度大于key长度

            StringBuilder stringBuilder = new StringBuilder(key);
            // 字符长度减去key长度后剩余的长度
            int minusLenth = charLength - keyLength;
            // 剩余长度除以要拼接的密钥的长度,得出要拼接几次密钥
            int divide = minusLenth / EncryptUtil.SUFFIX_KEY_LENTH;
            // 拼接密钥
            for (int j = 0; j < divide; j++) {
                stringBuilder.append(ConstantByMap.DEFAULT_KEY);
            }
            // 剩余长度余要拼接的密钥长度,得出拼完后还差几个字符
            int remainder = minusLenth % EncryptUtil.SUFFIX_KEY_LENTH;
            // 拼接剩余字符
            if (remainder != 0) {
                stringBuilder.append(ConstantByMap.DEFAULT_KEY.substring(0, remainder));
            }
            key = stringBuilder.toString();
        }
        b = key.getBytes();
        // 字符串每个字符减去key对应的字符
        for (int i = 0; i < charLength; i++) {
            data[i] -= b[i];
        }

        return data;
    }

}